import Vue from 'vue'
import VueRouter from 'vue-router'
import Layout from '@/vab/layouts'
import store from "@/store/index";
import _ from 'lodash'
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'

/* 多级路由不需要缓存时可放开注释直接引入 用法component:VabEmptyLayout*/
/* import VabEmptyLayout from '@/vab/layouts/VabEmptyLayout' */
import {publicPath, routerMode} from '@/config'
/*子路由容器（有缓存）*/
import SubRouterView from "@/layout/sub-router-view";
import {MenuTypeEnum} from "@/common/enum/common.enum";
import {RouterActionsEnum, UserGetterEnum, UserMutationEnum} from "@/store/enum/store.enum";
import LocalStorageUtil from "@/utils/local-storage-util";

Vue.use(VueRouter);
/*静态路由*/
export const constantRoutes = [
	// 默认首页（若后台设置可注释）
	{
		path: '/index-',
		component: Layout,
		meta: {title: '首页', icon: '', iconFont: ''},
		root: MenuTypeEnum.rootNode,
		children: [
			{
				path: '/index-',
				name: 'index-',
				meta: {title: '首页', icon: 'home-4-fill', iconFont: 'home-4-fill', iconActive: '', iconDefault: ''},
				component: () => import('@/views/index/index-manager'),
			},
		]
	},
	// 登录页
	{
		path: '/login',
		name: 'login',
		component: () => import('@/views/login'),
		hidden: true,
	},
	// 404页
	{
		path: '*',
		component: () => import('@/views/error-page/404'),
		meta: {title: '页面不存在', icon: ''},
		hidden: true
	},
	// 流程实例
	{
		path: '/instance-create',
		component: Layout,
		children: [
			{
				path: '/instance-create',
				name: 'instance-create',
				component: () => import('@/views/bpm/model/create-model/create-model'),
                meta: {title: 'label.workflowInfo', icon: '', tabHidden: false, nameI18nKey: 'label.workflowInfo'},
			}
		],
		hidden: true
	},

	// 其他系统杂项页
	{
		path: '/sys',
		component: Layout,
		meta: {title: '', icon: ''},
		hidden: true,
		children: [
			{
				path: '/user-center',
				name: 'user-center',
				meta: {title: '个人中心', icon: ''},
				component: () => import('@/views/system/user-center/user-center'),
			},
			{
				path: '/loading',
				name: 'loading',
				meta: {title: 'loading', icon: ''},
				component: () => import('@/views/error-page/loading-page'),
			},
		]
	},
]

/*动态路由*/
export let asyncRoutes = []

/*
 * 实例化路由
 */
const router = newRouter();
function newRouter(routes = constantRoutes) {
	return new VueRouter({
		base: publicPath,
		mode: routerMode,
		scrollBehavior: () => ({
			y: 0,
		}),
		routes: routes
	})
}

/**
 * 创建路由
 */
export function createRouter(data, list) {
	//创建可用的路由数据
	let deepIndex = 0;//用于递归层级判断
	setRoute(data, list, deepIndex);

	//第一级菜单必须加载layout布局组件
	list.forEach((item, index) => {
		//如果第一级直接是菜单，非菜单组
		if (item.type === MenuTypeEnum.node) {
			item.children = [_.cloneDeep(item)];
			item.root = MenuTypeEnum.rootNode;
			item.alwaysShow = false;
		} else {
			item.root = MenuTypeEnum.rootGroup;
		}
		const redirect = item.path;//默认拦截的path
		item.component = Layout;
		item.name = 'root-' + item.name;//添加一个根节点标识
		item.path = '/root' + item.path;//添加一个根节点
		if (index === 0) {//重新配置动态加载第一个默认路由（不需要默认加载后台的第一个路由的话可注释）
			item.path = '/';
			item.name = 'index';
			item.redirect = redirect;
		}
	});
	// 重设路由分配
	router.matcher = newRouter([...asyncRoutes,...constantRoutes]).matcher;
}
/**
 * 遍历处理菜单方法
 */
function setRoute(list, children, deepIndex) {
	list.forEach(item => {
		let obj = {
			path: item.modPath,
			name: item.code,
			code: item.code,
			alwaysShow: true,
			meta: {
				title: item.name,
				iconFont: item.iconFont,
				iconDefault: item.iconDefault,
				iconActive: item.iconActive,
				icon: item.iconDefault || item.iconFont,
				nameI18nKey: item.nameI18nKey || ''
			},
			children: []
		}
		//如果有子元素继续递归
		if (item.children && item.children.length > 0) {
			//如果是二级以上的路由，则增加一个路由容器
			if (deepIndex >= 1) {
				obj = {...obj, type: MenuTypeEnum.group, component: SubRouterView}
			} else {
				obj = {...obj, type: MenuTypeEnum.group}
			}
			deepIndex++;
			setRoute(item.children, obj.children, deepIndex);
		} else {
			const module = item.modPage;
			obj = {...obj, type: MenuTypeEnum.node, component: resolve => require(['@/views' + module], resolve)}
		}
		children.push(obj);
	});
}

/**
 * 查找第一个路由（子路由），默认第一个跳转路由
 */
function findFirstRouter(item) {
	if (item[0].type === MenuTypeEnum.group) {
		return findFirstRouter(item[0].children);
	}
	if (item[0].type === MenuTypeEnum.node) {
		return item[0];
	}
}

/**
 * 检查上一次登录的路由页面
 */
function checkPrevRouter(from, to, next) {
	// 获取上次登录的用户，如果相同则跳回上次退出的页面
	const prevUser = _.cloneDeep(store.getters[UserGetterEnum.prevUser]);
	const currentUser = store.getters[UserGetterEnum.userInfo];
	// 使用完立即清除上次登录用户的记录
	store.dispatch(UserMutationEnum.clearPrevUser);
	// 如果是上一次登录的用户，则跳转上一次停留的页面
	if (prevUser && prevUser === currentUser.username && asyncRoutes.length) {
		next({name: from.query.redirect, replace: true});
		return false;
	}
	// 如果是第一次登录或者上次登录的用户同，则清除切换的菜单标识，清除后台返回的菜单数据
	if (prevUser && prevUser !== currentUser.username && asyncRoutes.length) {
		LocalStorageUtil.deleteItem('asideActive');
		asyncRoutes = []
	}
}

/**
 * 全局路由拦截
 */
router.beforeEach((to, from, next) => {
	NProgress.start();
	const token = store.getters[UserGetterEnum.token];
	// 如果有token说明用户已登录，
	if (token) {
		// 禁止再返回登录页面，直接返回首页
		if (to.name === "login") {
			return router.replace({path: '/'});
		}
		// 检查上一次登录用户的路由
		checkPrevRouter(from, to, next);

		// 如果从登录页过来，或者刷新页面
		if ((!from.name || from.name === 'login') && asyncRoutes.length === 0) {
			// 从vuex中拿取菜单信息
			let storeMenuList = store.getters[UserGetterEnum.menuList];

			//处理生成路由数据
			createRouter(storeMenuList, asyncRoutes);

			// 菜单组件使用routes中存储数据
			store.dispatch(RouterActionsEnum.setRoutes);

			// 第一次登陆，查找第一个默认路由并跳转
			const firstRouter = findFirstRouter(asyncRoutes);
			if (from.name === 'login') {
				return next({name: firstRouter.name, replace: true});
			}
			return next({...to, replace: true});
		}
		next();
	} else {
		if (to.name === 'login') {
			next();
		} else {
			//否则跳忘登录页
			next({name: 'login', replace: true, query: {redirect: to.name}});
		}
	}
})
router.afterEach(transition => {
	NProgress.done();
});

/**
 * 不知道干啥的代码
 */
const originalPush = VueRouter.prototype.push
VueRouter.prototype.push = function push(location, onResolve, onReject) {
	if (onResolve || onReject) {
		return originalPush.call(this, location, onResolve, onReject)
	}else {
		return originalPush.call(this, location).catch((err) => err)
	}
}
export default router
